#ifndef CUBE_H_
#define CUBE_H_

#include "point.h"
#include "matrix4x4.h"
#include <cmath>
#include <set>


/*
	**** Coordenadas que utiliza el cubo ****

	 z(x3)
	  |
	  |
	  |
	  |_________  x(x1)
	 /
	/
   /
   y(x2)
				(front face)
  (0,0,1)        ^ z         (1,0,1)
		 p1 _____|_________p2
		  / 	 |		  /|
		 / |     |       / |
(0,1,1)	/        |      / (|1,1,1)
	 p4/___|___________/p3 |
	  |	   	(0,0,0)    |   |
	  |	   |p5_ _ _ _ _| _ |p6
	  |	 /			   |  /   (1,0,0)
	  |                | /
	  |/_______________|/
	p8			^		p7
	 (0,1,0)	|        (1,1,0)
				|
			(backFace)


*/



class Cube{
	private:
		static const Point points[8];

		Point _frontFace[4];
		Point _backFace[4];

	public:
		Cube();

		Cube(const Point& p1,const Point p2);

		/**
		 * Para crear Cubo tipo punto
		 */
		Cube(float x, float y, float z);

		Cube& translate(float dx,float dy,float dz);

		Point center()const;
		float width()const;
		float depth()const;
		float height()const;


		Cube& center(const Point& center);

		const Point* getNormalizedPoints();

		void rotate(float angle,const Point& center,const Point& axis);

		bool intersect(const Cube& c2);

		float minZ()const;
		float maxZ()const;
		float minX()const;
		float maxX()const;
		float minY()const;
		float maxY()const;

		bool operator <(const Cube& cube)const;

		Cube& shrink(float dx,float dy,float dz);
		Cube& extend(float dx,float dy,float dz);
		Cube& advance(const Point& direction,float amount);
		Cube& advance(const Point& direction);


		const Point* frontFace(){ return _frontFace; }
		const Point* backFace(){ return _backFace; }
	private:
		void getFaceIndices(std::set<unsigned int>& indices,unsigned int faceNumber);

		void calculateNormals(Point* normal)const;

		bool intersect(const Cube& c2,bool recursive)const;

		void createCubePoints(const Point& p1,const Point p2);

		float max(unsigned int coord)const;
		float min(unsigned int coord)const;

		//void calculateMatrix();
};

#endif /* CUBE_H_ */
